﻿Imports Automation.BDaq
Imports System.ComponentModel
Imports System.IO

Public Delegate Sub DeleDrawData()

Public Structure AiSetting

    Public brief As String
    Public lineColor As Color
    Public lineWidth As Integer
    Public max As Double
    Public min As Double
    Public ratio As Double
    Public index As Integer
    '真实值为 (vi + offset) * ratio
    Public offset As Double

End Structure

Public Class mainForm

    Dim MGraph As MaGraph '先声明图表类
    Dim tempDisplay As New TemperatureForm '温度窗口

#Region "实验数据保存相关"
    Dim sample_start_time As Date '实验开始的时间
    Dim sample_duration As TimeSpan
    Dim save_enable As Boolean = False
    Dim sample_seconds As Double = 0.0
    Dim sample_interval As Double
    Dim curr_path As String = Application.StartupPath '当前路径
    Dim file_cnt As UInteger = 1
    Dim file_path As String = curr_path + "/data-" + Date.Now.Ticks.ToString + "/"
    Dim file_name As String
    Dim file_dir_info As DirectoryInfo = New DirectoryInfo(file_path)

    ''' <summary>
    ''' 设置当前保存的文件名，如果文件大于50M则返回假
    ''' </summary>
    ''' <param name="index">文件名名称纯数字</param>
    Public Function setFile(index As UInteger) As Boolean
        Dim ret As Boolean = True
        file_name = index.ToString() + ".csv"
        Dim fis() As FileInfo = file_dir_info.GetFiles(file_name)
        If fis Is Nothing Or fis.Length = 0 Then
            Dim fs As FileStream = New FileStream(file_path + file_name, FileMode.CreateNew, FileAccess.ReadWrite)
            fs.Close()
        Else
            If fis(0).Length > 500000000 Then
                ret = False
            End If
        End If
        Return ret
    End Function

    Public Function getSaveFileName() As String
        If Not setFile(file_cnt) Then
            file_cnt += 1
            setFile(file_cnt)
        End If
        Return file_path + file_name
    End Function

#End Region

    Private _connected As Boolean = False
    Private WithEvents BufferAiCtrl As New WaveformAiCtrl()
    Public Ad As AdDevice 'Ai设备类
    Public channels(7) As AdChannel '通道列表
    Public chSettings(7) As AiSetting
    Private _deleSetHandler As New DeleUpdateSetting(AddressOf setHandler) '设置完毕后的委托
    Public WithEvents setForm As New channelSetting(_deleSetHandler, channels)
    Public dataDrawHandler As New DeleDrawData(AddressOf DrawData) '刷新曲线的委托

    ''' <summary>
    ''' 设置完毕后的回调函数
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub setHandler()

    End Sub

    ''' <summary>
    ''' 加载设置
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub loadSettings()
        txtDataLength.Text = My.Settings.dataLength
        txtDataPeriod.Text = My.Settings.dataPeriod
        txtFPS.Text = My.Settings.dataFPS
        txtWindowLength.Text = My.Settings.windowLength

        chSettings(0).lineColor = My.Settings.Ai0Color
        chSettings(0).lineWidth = My.Settings.Ai0LineWidth
        chSettings(0).max = My.Settings.Ai0Max
        chSettings(0).min = My.Settings.Ai0Min
        chSettings(0).brief = My.Settings.Ai0Brief
        chSettings(0).offset = My.Settings.Ai0Offset
        chSettings(0).ratio = My.Settings.Ai0Ratio

        chSettings(1).lineColor = My.Settings.Ai1Color
        chSettings(1).lineWidth = My.Settings.Ai1LineWidth
        chSettings(1).max = My.Settings.Ai1Max
        chSettings(1).min = My.Settings.Ai1Min
        chSettings(1).brief = My.Settings.Ai1Brief
        chSettings(1).offset = My.Settings.Ai1Offset
        chSettings(1).ratio = My.Settings.Ai1Ratio

        chSettings(2).lineColor = My.Settings.Ai2Color
        chSettings(2).lineWidth = My.Settings.Ai2LineWidth
        chSettings(2).max = My.Settings.Ai2Max
        chSettings(2).min = My.Settings.Ai2Min
        chSettings(2).brief = My.Settings.Ai2Brief
        chSettings(2).offset = My.Settings.Ai2Offset
        chSettings(2).ratio = My.Settings.Ai2Ratio
    End Sub

    ''' <summary>
    ''' 保存设置
    ''' </summary>
    ''' <remarks></remarks>
    Private Sub saveSettings()
        My.Settings.dataLength = Convert.ToDouble(txtDataLength.Text)
        My.Settings.dataPeriod = Convert.ToDouble(txtDataPeriod.Text)
        My.Settings.dataFPS = Convert.ToDouble(txtFPS.Text)
        My.Settings.windowLength = Convert.ToDouble(txtWindowLength.Text)

        My.Settings.Ai0Color = channels(0).lineColor
        My.Settings.Ai0LineWidth = channels(0).lineWidth
        My.Settings.Ai0Max = channels(0).max
        My.Settings.Ai0Min = channels(0).min
        My.Settings.Ai0Brief = channels(0).brief
        My.Settings.Ai0Offset = channels(0).offset
        My.Settings.Ai0Ratio = channels(0).ratio

        My.Settings.Ai1Color = channels(1).lineColor
        My.Settings.Ai1LineWidth = channels(1).lineWidth
        My.Settings.Ai1Max = channels(1).max
        My.Settings.Ai1Min = channels(1).min
        My.Settings.Ai1Brief = channels(1).brief
        My.Settings.Ai1Offset = channels(1).offset
        My.Settings.Ai1Ratio = channels(1).ratio

        My.Settings.Ai2Color = channels(2).lineColor
        My.Settings.Ai2LineWidth = channels(2).lineWidth
        My.Settings.Ai2Max = channels(2).max
        My.Settings.Ai2Min = channels(2).min
        My.Settings.Ai2Brief = channels(2).brief
        My.Settings.Ai2Offset = channels(2).offset
        My.Settings.Ai2Ratio = channels(2).ratio
    End Sub

    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim device_name As String
        MGraph = New MaGraph(zdMain) '创建窗体的时候初始化
        MGraph.SetTitle("压力传感器数据")
        Me.ActiveControl = Me.zdMain '设置焦点位置为图

        loadSettings()

        '创建临时目录，用于保存曲线
        Directory.CreateDirectory(file_path)
        tempDisplay.Show()
        tempDisplay.setPath(file_path)

        '通道配置初始化
        For i As Integer = 0 To 7
            chSettings(i).index = i
            If chSettings(i).lineColor.Name = "0" Then
                chSettings(i).lineColor = AdChannel.lineColors(i)
            End If
            If channels(i) Is Nothing Then
                If i > 2 Then
                    chSettings(i).lineWidth = chSettings(2).lineWidth
                    chSettings(i).ratio = chSettings(2).ratio
                    chSettings(i).max = chSettings(2).max
                    chSettings(i).min = chSettings(2).min
                    chSettings(i).offset = chSettings(2).offset
                    chSettings(i).brief = "Ai" + i.ToString()
                End If
                channels(i) = New AdChannel(chSettings(i))
            End If
        Next

        '搜索安装的板卡
        If DeviceCtrl.InstalledDevices.Count > 0 Then
            Dim usbIndex As Integer = -1 'usb板卡的索引
            For i As Integer = 0 To DeviceCtrl.InstalledDevices.Count - 1
                device_name = DeviceCtrl.InstalledDevices.Item(i).ToString
                Me.cbDeviceList.Items.Add(device_name)
                If device_name.Contains("USB") Then
                    usbIndex = i
                End If
            Next

            If usbIndex < 0 Then
                MsgBox("没有找到USB板卡！")
                Me.cbDeviceList.SelectedItem = Me.cbDeviceList.Items(0)
                usbIndex = 0
            Else
                Me.cbDeviceList.SelectedItem = Me.cbDeviceList.Items(usbIndex)
            End If

            Try
                BufferAiCtrl.SelectedDevice = New DeviceInformation(usbIndex)
                Ad = New AdDevice(BufferAiCtrl)
                setOnline()
            Catch ex As Exception
                MsgBox(ex.Message, MsgBoxStyle.Critical)
            End Try

        Else
            MsgBox("没有找到板卡！")
        End If
    End Sub

    ''' <summary>
    ''' 设置板卡状态为在线
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub setOnline()
        _connected = True
        bottomStatus.Items("sysStatus").Text = "Connected"
        bottomStatus.Items("sysStatus").BackColor = Color.Green
        '如果设备可用，默认勾选两个通道
        checkChannels.SetItemChecked(0, True)
        checkChannels.SetItemChecked(1, True)
    End Sub

    Public Sub setOffline()
        _connected = False
        bottomStatus.Items("sysStatus").Text = "Not Connected"
        bottomStatus.Items("sysStatus").BackColor = Color.Red
    End Sub

    Private Sub btnStart_Click(sender As Object, e As EventArgs) Handles btnStart.Click
        Dim rate As Integer '采样率
        Dim fps As Double '刷新速率
        If Ad IsNot Nothing Then
            Ad.axisXMax = txtWindowLength.Text
        End If
        If _connected Then
            If BufferAiCtrl.State <> ControlState.Running Then
                '记录开始时间
                sample_start_time = Date.Now
                save_enable = True
                Timer1.Start()

                Dim section_len As Integer
                Ad.selectedChs.Clear() '清空之前选中的通道
                '获取选中的通道
                For i As Integer = 0 To checkChannels.Items.Count - 1
                    If (checkChannels.GetItemChecked(i)) Then
                        Ad.selectedChs.Add(i)
                    End If
                Next
                rate = Convert.ToInt32(cbSampleRate.Text)
                sample_interval = 1.0 / rate '采样周期
                fps = Convert.ToDouble(txtFPS.Text)
                section_len = rate / fps
                ReDim Ad.axisXData(section_len - 1)

                '初始化x轴
                For i As Integer = 0 To section_len - 1
                    Ad.axisXData(i) = i / rate
                Next
                MGraph.InitAxis(Ad, channels)
                Ad.begin(rate, section_len)
            End If
        End If
    End Sub

    ''' <summary>
    ''' 绘制曲线，同时保存文件
    ''' </summary>
    ''' <remarks></remarks>
    Public Sub DrawData()
        For Each ch_index As Integer In Ad.selectedChs
            channels(ch_index).GetData(Ad)
        Next

        Dim save_curve As Action = Sub()
                                       Dim saver As New StreamWriter(getSaveFileName(), append:=True)
                                       Dim data As String
                                       For i As Integer = 0 To channels(Ad.selectedChs(0)).buffer.Length - 1
                                           sample_seconds += sample_interval
                                           data = Date.Now.ToString("G") + "," + sample_seconds.ToString + ","
                                           For Each ch_index As Integer In Ad.selectedChs
                                               data += channels(ch_index).buffer(i).ToString
                                               data += ","
                                           Next
                                           saver.WriteLine(data)
                                       Next
                                       saver.Close()
                                   End Sub

        If save_enable Then
            save_curve()
        End If

        MGraph.RefreshCurve(Ad, channels)
    End Sub

    Private Sub btnStop_Click(sender As Object, e As EventArgs) Handles btnStop.Click
        If _connected Then
            Ad.stop()
        End If
        save_enable = False
        Timer1.Stop()
    End Sub

    Private Sub SettingsToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles SettingsToolStripMenuItem.Click

    End Sub

    ''' <summary>
    ''' AD采样完成后的回调
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="args"></param>
    ''' <remarks></remarks>
    Private Sub dataReadyHandler(ByVal sender As Object, ByVal args As BfdAiEventArgs) Handles BufferAiCtrl.DataReady
        BufferAI.GetBufferData(BufferAiCtrl, Ad.buffAiData)
        'Debug.Print("get data")
        Me.Invoke(dataDrawHandler)
    End Sub

    ''' <summary>
    ''' 设置窗体销毁事件处理
    ''' </summary>
    ''' <param name="sender"></param>
    ''' <param name="e"></param>
    ''' <remarks></remarks>
    Private Sub setFormDespose(sender As Object, e As EventArgs) Handles setForm.FormClosed
        Me.setForm = Nothing
    End Sub

    ''' <summary>
    ''' 更行视窗长度
    ''' </summary>
    Private Sub txtWindowLength_TextChanged(sender As Object, e As EventArgs) Handles txtWindowLength.TextChanged
        If Ad IsNot Nothing Then
            Try
                Ad.axisXMax = Convert.ToDouble(txtWindowLength.Text)
            Catch ex As Exception

            End Try
        End If
    End Sub

    Private Sub mainForm_FormClosing(sender As Object, e As FormClosingEventArgs) Handles MyBase.FormClosing
        If Ad IsNot Nothing Then
            Ad.stop()
        End If

        saveSettings()
    End Sub

    Private Sub setting_channel_Click(sender As Object, e As EventArgs) Handles setting_channel.Click
        If setForm Is Nothing Then
            setForm = New channelSetting(_deleSetHandler, channels)
        End If
        setForm.ShowChannelSetting()
        setForm.Show()
    End Sub

    Private Sub setting_temperature_Click(sender As Object, e As EventArgs) Handles setting_temperature.Click
        If tempDisplay.Visible Then
            setting_temperature.Text = "显示温度"
            tempDisplay.Hide()
        Else
            setting_temperature.Text = "隐藏温度"
            tempDisplay.Show()
        End If
    End Sub

    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        sysRunningTime.Text = (Date.Now - sample_start_time).ToString("c").Substring(0, 8)
        sample_duration = Date.Now - sample_start_time
        Dim seconds As Integer = sample_duration.TotalSeconds()
        seconds = seconds Mod Int(Convert.ToDouble(txtDataPeriod.Text) * 60)
        If seconds < Int(Convert.ToDouble(txtDataLength.Text) * 60) Then
            save_enable = True
        Else
            save_enable = False
        End If
    End Sub
End Class
